package com.yunda.nebula.gateway.service;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Random;

/**
 * \* User: wei.zhang
 * \* Date: 2019/12/25 15:48
 * \* Description:
 *
 * @author wei.zhang
 * \
 */
@Slf4j
//@Service
//@Primary
public class IpHashRibbonRule extends AbstractLoadBalancerRule {
    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {

    }

    /**
     * 调用哪个server
     */
    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        String realIp = String.valueOf(key);
        log.info("页面请求真实IP：{}",realIp);
        Server server = null;
        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            //当前存活的服务
            List<Server> upList = lb.getReachableServers();
            //获取全部的服务
            List<Server> allList = lb.getAllServers();

            if (CollectionUtils.isEmpty(upList)||CollectionUtils.isEmpty(allList)){
                return null;
            }
            int index = chooseServiceWithIp(upList.size(),realIp);
            server = upList.get(index);
            if (server.isAlive()){
                return server;
            }
//            for (Server s : upList) {
//                if (realIp.contains(s.getHost())) {
//                    server = s;
//                    log.info("服务请求分发到实例：{}",s.getId());
//                    break;
//                }
//            }
//
//            if (server == null) {
//                Thread.yield();
//                continue;
//            }
//            if (server.isAlive()) {
//                return (server);
//            }
//            Random random = new Random();
//            server = upList.get(random.nextInt(upList.size()));
//            Thread.yield();
        }
        return server;
    }

    private int chooseServiceWithIp(int size, String realIp) {
        Integer index = Math.abs(realIp.hashCode()) % size;
        return index;
    }

//    public static void main(String[] args) {
//        String ip = "1.2.3.5";
//        Integer index = Math.abs(ip.hashCode()) % 5;
//        System.out.println(index);
//    }

}
